package com.ctshk.rpc.user.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.utils.CalcMemberLevelUtil;
import com.ctshk.rpc.hotel.dto.HotelOrderDTO;
import com.ctshk.rpc.hotel.service.IHotelOrderService;
import com.ctshk.rpc.order.air.dto.AirOrderDTO;
import com.ctshk.rpc.order.air.service.IAirOrderService;
import com.ctshk.rpc.order.airexpress.dto.AirportExpressOrderDTO;
import com.ctshk.rpc.order.airexpress.service.IAirportExpressOrderService;
import com.ctshk.rpc.order.bus.dto.BusOrderDTO;
import com.ctshk.rpc.order.bus.service.IBusOrderService;
import com.ctshk.rpc.order.localfun.dto.AddIntegralLocalFunOrderDTO;
import com.ctshk.rpc.order.localfun.service.ILocalFunOrderService;
import com.ctshk.rpc.order.scenic.dto.AddIntegralScenicOrder;
import com.ctshk.rpc.order.scenic.service.IScenicOrderService;
import com.ctshk.rpc.order.season.dto.SeasonOrderDTO;
import com.ctshk.rpc.order.season.service.ISeasonOrderService;
import com.ctshk.rpc.order.ship.dto.ShipOrderDTO;
import com.ctshk.rpc.order.ship.service.IShipOrderService;
import com.ctshk.rpc.order.tour.dto.SeriesOrderDTO;
import com.ctshk.rpc.order.tour.service.ISeriesOrderService;
import com.ctshk.rpc.order.train.dto.TrainOrderDTO;
import com.ctshk.rpc.order.train.service.ITrainOrderService;
import com.ctshk.rpc.starvip.dto.start_vip.user.Contact;
import com.ctshk.rpc.starvip.dto.start_vip.user.LoyMember;
import com.ctshk.common.enums.appUser.TransactionType;
import com.ctshk.rpc.starvip.req.TransactionIntegralCommonReq;
import com.ctshk.rpc.starvip.req.member.UpdateMemberTierReq;
import com.ctshk.rpc.starvip.req.user.UserInfoQueryReq;
import com.ctshk.rpc.starvip.service.IStarVipBusinessService;
import com.ctshk.rpc.starvip.service.IStarVipMemberService;
import com.ctshk.rpc.starvip.service.IStarVipUserService;
import com.ctshk.rpc.user.req.UpdateUserReq;
import com.ctshk.rpc.user.req.UserTransactionIntegralCommonReq;
import com.ctshk.rpc.user.service.ITransactionIntegralService;
import com.ctshk.rpc.user.service.IUserService;
import com.ctshk.rpc.user.service.IUserStarVipService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

/**
 * <p>
 *
 * </p>
 *
 * @author 李新科
 * @date 2021/6/28 10:49
 */
@Slf4j
@DubboService
public class UserStarVipServiceImpl implements IUserStarVipService {

    @DubboReference
    private IStarVipBusinessService starVipBusinessService;

    @DubboReference
    private IStarVipMemberService starVipMemberService;

    @DubboReference
    private IStarVipUserService starVipUserService;

    @DubboReference
    private ISeriesOrderService seriesOrderService;

    @DubboReference
    private ISeasonOrderService seasonOrderService;

    @DubboReference
    private IHotelOrderService hotelOrderService;

    @DubboReference
    private IAirOrderService airOrderService;

    @DubboReference
    private ITrainOrderService trainOrderService;

    @DubboReference
    private IShipOrderService shipOrderService;

    @DubboReference
    private IBusOrderService busOrderService;

    @DubboReference
    private IAirportExpressOrderService airportExpressOrderService;

    @DubboReference
    private IScenicOrderService scenicOrderService;

    @DubboReference
    private ILocalFunOrderService localFunOrderService;

    @DubboReference
    private IUserService userService;
    
    @DubboReference
    private ITransactionIntegralService transactionIntegralService;

    @Override
    public Result addPoints(String jobParams) {
        log.info("定时任务参数: %s",jobParams);
        boolean json = JSONUtil.isJson(jobParams);
        if(!json) {
            return Result.failed(new BusinessException(SystemError.SYS_428,"day"));
        }
        JSONObject jsonObject = JSONUtil.parseObj(jobParams);
        Long day = jsonObject.getLong("day",7L);
        LocalDate localDate  = LocalDateTime.now().minusDays(day).toLocalDate();
        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(localDate, LocalTime.MAX);
        // 旅行团
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.OUTBOUND_TRAVEL;
            printLogStart(systemBusinessType);
            List<SeriesOrderDTO> dtoList = seriesOrderService.queryOrderDTOList(start, end);
            for (SeriesOrderDTO orderDTO : dtoList) {
                try {
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && orderDTO.getOrderStatus().equals(1)) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getTotalPrice())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getOrderStatus())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 自由行
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.FIXED_PACKAGE_TICKET;
            printLogStart(systemBusinessType);
            List<SeasonOrderDTO> dtoList = seasonOrderService.queryOrderDTOList(start, end);
            for (SeasonOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(null)
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getReceivableAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 酒店
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.HOTEL;
            printLogStart(systemBusinessType);
            List<HotelOrderDTO> dtoList = hotelOrderService.queryOrderDTOList(start, end);
            for (HotelOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getReceivableAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 机票
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.AIR_TICKET;
            printLogStart(systemBusinessType);
            List<AirOrderDTO> dtoList = airOrderService.queryOrderDTOList(start, end);
            for (AirOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getReceivableAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 火车票
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.TRAIN_TICKET;
            printLogStart(systemBusinessType);
            List<TrainOrderDTO> dtoList = trainOrderService.queryOrderDTOList(start, end);
            for (TrainOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getReceivableAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 船票
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.SHIP_TICKET;
            printLogStart(systemBusinessType);
            List<ShipOrderDTO> dtoList = shipOrderService.queryOrderDTOList(start, end);
            for (ShipOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getReceivableAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 巴士票
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.BUS_TICKET;
            printLogStart(systemBusinessType);
            List<BusOrderDTO> dtoList = busOrderService.queryOrderDTOList(start, end);
            for (BusOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getReceivableAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 机场快线
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.AIR_EXPRESS;
            printLogStart(systemBusinessType);
            List<AirportExpressOrderDTO> dtoList = airportExpressOrderService.queryOrderDTOList(start, end);
            for (AirportExpressOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getReceivableAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 景点门票
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.ATTRACTION_TICKET;
            printLogStart(systemBusinessType);
            List<AddIntegralScenicOrder> dtoList = scenicOrderService.queryOrderDTOList(start, end);
            for (AddIntegralScenicOrder orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getOrderAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        // 当地玩乐
        CompletableFuture.runAsync(() -> {
            SystemBusinessType systemBusinessType = SystemBusinessType.LOCAL_FUN;
            printLogStart(systemBusinessType);
            List<AddIntegralLocalFunOrderDTO> dtoList = localFunOrderService.queryOrderDTOList(start, end);
            for (AddIntegralLocalFunOrderDTO orderDTO : dtoList) {
                try {
                    orderDTO.setPaymentStatus(orderDTO.getPaymentStatus() == null?0:orderDTO.getPaymentStatus());
                    if(StringUtils.isNotBlank(orderDTO.getMemberId()) && OrderScheduledStatus.RESERVE_SUCCESS.getCode().equals(orderDTO.getScheduledStatus())) {
                        Result result = transactionIntegralService.transactionIntegralCommon(new UserTransactionIntegralCommonReq()
                                .setMemberId(orderDTO.getMemberId())
                                .setOrderNumber(orderDTO.getOrderNumber())
                                .setSystemBusinessType(systemBusinessType.getCode())
                                .setReceivableAmount(orderDTO.getOrderAmount())
                                .setCurrency(Currency.HKD.getCurrency())
                                .setTransactionType(TransactionType.ADD.getCode())
                                .setOrderSource(orderDTO.getSource())
                        );
                        if(result.isSuccess()) {
                            //增加积分成功查询会员积分是否满足升级条件
                            rating(orderDTO.getMemberId(),orderDTO.getUserId());
                        } else {
                            throw new RuntimeException(result.getMsg());
                        }
                    }
                } catch (Exception e) {
                    printErrorLog(systemBusinessType,orderDTO.getId(), orderDTO.getOrderNumber(), e);
                    
                }
            }
            printLogEnd(systemBusinessType);
        });

        return Result.success();
    }


    /**
     * 查询会员信息根据积分和消费次数评级
     * @param memberId
     */
    private void rating(String memberId,Long userId) {
        try {
            Result<Contact> contactResult = starVipUserService.userInfoQuery(new UserInfoQueryReq()
                    .setId(String.valueOf(memberId)));
            if(contactResult.isSuccess()) {
                Contact data = contactResult.getData();
                LoyMember loyMember = null;
                List<LoyMember> loyMemberList = data.getListOfLoyMember().getLoyMember();
                for (LoyMember loyMember2 : loyMemberList) {
                    if(loyMember2.getId().equals(memberId)) {
                        loyMember = loyMember2;
                    }
                }
                // 定级交易次数
                int ratingConsumptionTimes = Integer.valueOf(loyMember.getPoint2Value());
                // 定级积分
                int ratingPoint = Integer.valueOf(loyMember.getPoint3Value());

                int level = CalcMemberLevelUtil.calcRatingLevel(ratingPoint, ratingConsumptionTimes);
                MemberLevel memberLevel = MemberLevel.getByLevel(level);
                if(Objects.nonNull(memberLevel)) {
                    Result result = starVipMemberService.updateTier(new UpdateMemberTierReq()
                            .setId(memberId)
                            .setCtsLowestTier(memberLevel.getMemberTierName()));
                    if(result.isSuccess()) {
                        userService.update(new UpdateUserReq()
                                .setId(userId)
                                .setMemberLevel(level)
                                .setUpgradePoints(memberLevel.getRatingPoint())
                                .setConsumptionTimes(memberLevel.getRatingConsumptionTimes())
                        );
                    } else {
                        throw new RuntimeException(result.getMsg());
                    }
                }

            }
        } catch (Exception e) {
            log.error(String.format("会员[%s]升级失败: ",memberId),e);
            e.printStackTrace();
        }

    }

    private void printLogStart(SystemBusinessType systemBusinessType) {
        log.info(String.format("========================================== [%s]订单增加积分开始 ========================================== ",systemBusinessType.getValue()));
    }

    private void printLogEnd(SystemBusinessType systemBusinessType) {
        log.info(String.format("========================================== [%s]订单增加积分结束 ========================================== ",systemBusinessType.getValue()));
    }

    private void printErrorLog(SystemBusinessType systemBusinessType,Long orderId,String orderNumber,Exception e) {
        log.error(String.format("%s订单id: [%s],订单编号: [%s] 积分增加失败,原因: %s",systemBusinessType.getValue(),orderId,orderNumber,e.getMessage()));
    }
}
